Skip to content

Add pyroscope for observability#21167

Merged
AlexsanderHamir merged 5 commits intomainfrom
litellm_embeddings_latency_issue_0001
Feb 14, 2026
Merged

Add pyroscope for observability#21167
AlexsanderHamir merged 5 commits intomainfrom
litellm_embeddings_latency_issue_0001

Conversation

@AlexsanderHamir
Copy link
Contributor

Relevant issues

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have Added testing in the tests/litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

CI (LiteLLM team)

CI status guideline:

  • 50-55 passing tests: main is stable with minor issues.
  • 45-49 passing tests: acceptable but needs attention
  • <= 40 passing tests: unstable; be careful with your merges and assess the risk.
  • Branch creation CI run
    Link:

  • CI run for the last commit
    Link:

  • Merge / cherry-pick CI run
    Links:

Type

🆕 New Feature

Changes

…dd UTF-8 locale hint

- No defaults for PYROSCOPE_APP_NAME or PYROSCOPE_SERVER_ADDRESS; fail at startup if unset when Pyroscope is enabled
- Set LANG/LC_ALL to C.UTF-8 when unset to reduce malformed_profile (invalid UTF-8) rejections
- Startup message suggests PYTHONUTF8=1 if server rejects profiles
- Simplify LITELLM_ENABLE_PYROSCOPE in config_settings; document Pyroscope env vars as required with no default
- Add pyroscope_profiling to sidebar (Alerting & Monitoring)
- pyproject.toml: pyroscope-io as required dep on non-Windows (marker), in proxy extra
- Add optional PYROSCOPE_SAMPLE_RATE env (integer, no default)
- Pass sample_rate to pyroscope.configure() as int for pyroscope-io
- Replace print with verbose_proxy_logger (info/warning)
- Document PYROSCOPE_SAMPLE_RATE in config_settings.md
@vercel
Copy link

vercel bot commented Feb 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Error Error Feb 14, 2026 1:33am

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 14, 2026

Greptile Overview

Greptile Summary

This PR adds optional Grafana Pyroscope continuous CPU profiling to the LiteLLM proxy, gated behind the LITELLM_ENABLE_PYROSCOPE environment variable. When enabled, it sends profiling data to a configured Pyroscope server. The implementation follows the existing pattern established by the Datadog tracer/profiler integration (_init_dd_tracer).

  • Critical: pyroscope-io is not marked as optional = true in pyproject.toml, making it a required dependency for all litellm installations (including SDK-only users). This adds a native C extension (cffi) to every install and will fail on unsupported platforms.
  • Missing documentation page: Both sidebars.js and config_settings.md reference proxy/pyroscope_profiling, but no corresponding .md file is included in the PR, resulting in broken doc links.
  • No tests included: The PR checklist requires at least 1 test in tests/litellm/, but none are provided. A unit test for _init_pyroscope() (e.g., verifying it returns cleanly when disabled, raises on missing config) would be straightforward to add.
  • Docstring inaccuracy: The method docstring claims PYROSCOPE_SERVER_ADDRESS defaults to http://localhost:4040 and PYROSCOPE_SAMPLE_RATE is a float, but the implementation requires the server address (no default) and parses sample rate as an integer.

Confidence Score: 2/5

  • This PR has a dependency configuration bug that will affect all litellm installations and is missing required documentation and tests.
  • The core Pyroscope integration logic is reasonable and follows existing patterns, but the missing optional = true flag on the pyroscope-io dependency is a significant packaging issue that would affect all users. Additionally, the missing documentation page will cause broken links, and no tests are provided as required by the contribution checklist.
  • Pay close attention to pyproject.toml (missing optional flag) and docs/my-website/sidebars.js (broken doc reference).

Important Files Changed

Filename Overview
pyproject.toml pyroscope-io dependency is missing optional = true, making it a required dependency for all litellm installations instead of being proxy-only.
litellm/proxy/proxy_server.py Adds _init_pyroscope() classmethod to ProxyStartupEvent. Logic is sound but logs an info-level message on every startup even when disabled, which is noisy. Missing documentation page referenced in sidebar and config docs.
poetry.lock Adds pyroscope-io 0.8.16 to lock file. Reflects the incorrect optional = false from pyproject.toml. Also bumps Poetry version and litellm-proxy-extras version.
docs/my-website/docs/proxy/config_settings.md Adds four new environment variable descriptions for Pyroscope configuration. References a documentation page (/proxy/pyroscope_profiling) that doesn't exist in this PR.
docs/my-website/sidebars.js Adds proxy/pyroscope_profiling to sidebar under Alerting & Monitoring. The referenced doc page does not exist in this PR, which will cause a broken link.

Flowchart

flowchart TD
    A[Proxy Startup] --> B{LITELLM_ENABLE_PYROSCOPE=true?}
    B -- No --> C[Log disabled, return]
    B -- Yes --> D{import pyroscope}
    D -- ImportError --> E[Log warning: pyroscope-io not installed]
    D -- Success --> F{PYROSCOPE_APP_NAME set?}
    F -- No --> G[Raise ValueError - crash startup]
    F -- Yes --> H{PYROSCOPE_SERVER_ADDRESS set?}
    H -- No --> G
    H -- Yes --> I[Build configure_kwargs]
    I --> J{PYROSCOPE_SAMPLE_RATE set?}
    J -- Yes, valid --> K[Add sample_rate to kwargs]
    J -- Yes, invalid --> G
    J -- No --> L[pyroscope.configure]
    K --> L
    L --> M[Log success, profiling active]
Loading

Last reviewed commit: 0cbea29

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

@@ -107,7 +107,8 @@ const sidebars = {
items: [
"proxy/alerting",
"proxy/pagerduty",
"proxy/prometheus"
"proxy/prometheus",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing documentation page

The sidebar references proxy/pyroscope_profiling, and config_settings.md links to /proxy/pyroscope_profiling, but no corresponding documentation file (docs/my-website/docs/proxy/pyroscope_profiling.md) is included in this PR. This will cause a broken link in the docs site at build time or at runtime.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 14, 2026

Additional Comments (2)

litellm/proxy/proxy_server.py
Noisy info log when disabled

This logs at info level on every proxy startup, even though Pyroscope is disabled by default. The Datadog tracer (_init_dd_tracer) doesn't log anything when its feature flag is off. Consider changing this to debug level to avoid cluttering logs for the vast majority of users who don't use Pyroscope.

        if not get_secret_bool("LITELLM_ENABLE_PYROSCOPE", False):
            verbose_proxy_logger.debug(
                "LiteLLM: Pyroscope profiling is disabled (set LITELLM_ENABLE_PYROSCOPE=true to enable)."
            )
            return

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!


litellm/proxy/proxy_server.py
Stale docstring

The docstring says PYROSCOPE_SERVER_ADDRESS (default http://localhost:4040) and PYROSCOPE_SAMPLE_RATE (float, no default), but the implementation requires PYROSCOPE_SERVER_ADDRESS (no default — raises ValueError if missing) and parses PYROSCOPE_SAMPLE_RATE as an integer via int(float(...)). The docstring should match the actual behavior.

        Sends profiles to PYROSCOPE_SERVER_ADDRESS (required, no default).
        Optional: PYROSCOPE_SAMPLE_RATE (integer, no default) to set the sample rate.

- pyproject.toml: mark pyroscope-io as optional=true (proxy extra only)
- Add docs/my-website/docs/proxy/pyroscope_profiling.md (fix broken sidebar link)
- Add tests/test_litellm/proxy/test_pyroscope.py for _init_pyroscope()
- proxy_server: fix _init_pyroscope docstring (required server/app name, sample rate as int)
@AlexsanderHamir AlexsanderHamir force-pushed the litellm_embeddings_latency_issue_0001 branch from 7eb3ed0 to dfa0293 Compare February 14, 2026 01:13
@AlexsanderHamir
Copy link
Contributor Author

@greptileai

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 14, 2026

Greptile Overview

Greptile Summary

Adds optional Grafana Pyroscope continuous CPU profiling to the LiteLLM proxy, gated behind the LITELLM_ENABLE_PYROSCOPE environment variable (off by default). The implementation follows the established pattern used by the Datadog tracer integration in ProxyStartupEvent.

  • Adds _init_pyroscope() classmethod to ProxyStartupEvent with validation for required env vars (PYROSCOPE_APP_NAME, PYROSCOPE_SERVER_ADDRESS), optional PYROSCOPE_SAMPLE_RATE, and graceful ImportError handling when the package is not installed.
  • Adds pyroscope-io as an optional dependency with sys_platform != 'win32' marker, included in the proxy extras group.
  • Includes new documentation page (pyroscope_profiling.md) with setup instructions and environment variable reference.
  • Adds mock-only unit tests covering disabled state, missing config validation, and sample rate parsing (missing ImportError branch coverage).
  • Minor style issues: info-level log on every startup when disabled (should be debug), and extraneous blank lines in pyproject.toml.

Confidence Score: 4/5

  • This PR is safe to merge — the feature is opt-in, off by default, and isolated to startup initialization with no impact on the request path.
  • The implementation is clean, follows existing patterns (DD tracer), and is fully gated behind an env var. The dependency is correctly marked as optional in pyproject.toml. Only minor style issues found (log level, extra blank lines, missing test for ImportError path). The lock file inconsistency (optional=false) was already flagged in a previous review thread.
  • Pay attention to poetry.lock — the optional = false inconsistency with pyproject.toml was noted in a prior review thread and should be resolved before merge.

Important Files Changed

Filename Overview
litellm/proxy/proxy_server.py Adds _init_pyroscope() classmethod to ProxyStartupEvent that optionally configures Pyroscope CPU profiling at startup. Clean implementation following the existing DD tracer pattern, with proper validation and ImportError handling. Minor concern about info-level logging when disabled.
pyproject.toml Adds pyroscope-io as an optional dependency with sys_platform != 'win32' marker and includes it in the proxy extra group. Two extraneous blank lines introduced between sections.
poetry.lock Lock file adds pyroscope-io 0.8.16 with optional = false which is inconsistent with pyproject.toml (optional = true). Lock file was regenerated with a different Poetry version (2.2.1 vs 2.1.4). Already flagged in previous review thread.
tests/test_litellm/proxy/test_pyroscope.py Good set of mock-only unit tests covering disabled path, missing config validation, and sample rate parsing. Missing test for the ImportError branch when pyroscope-io is not installed.
docs/my-website/docs/proxy/pyroscope_profiling.md New documentation page for Pyroscope profiling with clear setup instructions, environment variable reference, and platform notes.
docs/my-website/sidebars.js Adds pyroscope_profiling entry to the monitoring sidebar section alongside alerting, pagerduty, and prometheus.
docs/my-website/docs/proxy/config_settings.md Documents the four new Pyroscope-related environment variables in the config settings reference table.

Sequence Diagram

sequenceDiagram
    participant FastAPI as FastAPI Lifespan
    participant PSE as ProxyStartupEvent
    participant Env as Environment Variables
    participant Pyroscope as pyroscope-io

    FastAPI->>PSE: proxy_startup_event()
    PSE->>PSE: _init_pyroscope()
    PSE->>Env: get_secret_bool("LITELLM_ENABLE_PYROSCOPE")
    alt Disabled (default)
        Env-->>PSE: False
        PSE-->>PSE: return (log debug)
    else Enabled
        Env-->>PSE: True
        PSE->>Pyroscope: import pyroscope
        alt ImportError
            Pyroscope-->>PSE: ImportError
            PSE-->>PSE: log warning, continue
        else Imported OK
            PSE->>Env: PYROSCOPE_APP_NAME
            PSE->>Env: PYROSCOPE_SERVER_ADDRESS
            alt Missing required config
                PSE-->>FastAPI: raise ValueError (crash startup)
            else Config valid
                PSE->>Env: PYROSCOPE_SAMPLE_RATE (optional)
                PSE->>Pyroscope: pyroscope.configure(app_name, server_address, tags, sample_rate)
                Pyroscope-->>PSE: Profiling started
                PSE-->>PSE: log info
            end
        end
    end
Loading

Last reviewed commit: e604a04

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

Comment on lines 125 to +127



Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extraneous blank lines added

Two extra blank lines were introduced here. The rest of the file uses single blank lines between sections.

Suggested change

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

):
ProxyStartupEvent._init_pyroscope()
call_kw = mock_pyroscope.configure.call_args[1]
assert call_kw["sample_rate"] == 100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test for ImportError branch

The _init_pyroscope method has an except ImportError branch (line 5879 of proxy_server.py) that logs a warning when pyroscope-io is not installed but the feature is enabled. This code path is not covered by any test. Consider adding a test that patches sys.modules to raise ImportError for pyroscope when the feature is enabled, to verify the warning is logged and the proxy continues without crashing.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
@AlexsanderHamir AlexsanderHamir merged commit 30b28da into main Feb 14, 2026
7 of 22 checks passed
krrishdholakia pushed a commit that referenced this pull request Feb 14, 2026
…ctions (#21192)

* Access groups UI

* new badge changes

* adding tests

* fix: add custom_body parameter to endpoint_func in create_pass_through_route (#20849)

* fix: add custom_body parameter to endpoint_func in create_pass_through_route

The bedrock_proxy_route calls `endpoint_func(custom_body=data)` to
pass a pre-parsed, SigV4-signed request body. However, the
`endpoint_func` closure created by `create_pass_through_route` does
not accept a `custom_body` keyword argument, causing:

    TypeError: endpoint_func() got an unexpected keyword argument 'custom_body'

Add `custom_body: Optional[dict] = None` to both `endpoint_func`
definitions (adapter-based and URL-based). In the URL-based path,
when `custom_body` is provided by the caller, use it instead of
re-parsing the body from the raw request.

Fixes #16999

* Add tests for custom_body handling in create_pass_through_route

Address reviewer feedback on PR #20849:

- Document why the adapter-based endpoint_func accepts custom_body
  for signature compatibility but does not forward it (the underlying
  chat_completion_pass_through_endpoint does not support it).
- Add test_create_pass_through_route_custom_body_url_target: verifies
  that when a caller (e.g. bedrock_proxy_route) supplies custom_body,
  it takes precedence over the body parsed from the raw request.
- Add test_create_pass_through_route_no_custom_body_falls_back:
  verifies that the default path (no custom_body) correctly uses the
  request-parsed body, preserving existing behavior.

Both tests are fully mocked following the project's CONTRIBUTING.md
guidelines and the patterns established in the existing test file.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: themavik <themavik@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* change to model name for backwards compat

* addressing comments

* allow editing of access group names

* fix: populate identity fields in proxy admin JWT early-return path (#21169)

* fix: populate identity fields in proxy admin JWT early-return path

When is_proxy_admin is True, the UserAPIKeyAuth early-return now includes
user_id, team_id, team_alias, team_metadata, org_id, and end_user_id
resolved from the JWT. Previously only user_role and parent_otel_span
were set, causing blank Team Name and Internal User in Request Logs UI.

* test: add unit tests for proxy admin JWT identity fields

* bump: version 0.4.36 → 0.4.37

* migration + build files

* Add pyroscope for observability (#21167)

* Pyroscope: require PYROSCOPE_APP_NAME and PYROSCOPE_SERVER_ADDRESS, add UTF-8 locale hint

- No defaults for PYROSCOPE_APP_NAME or PYROSCOPE_SERVER_ADDRESS; fail at startup if unset when Pyroscope is enabled
- Set LANG/LC_ALL to C.UTF-8 when unset to reduce malformed_profile (invalid UTF-8) rejections
- Startup message suggests PYTHONUTF8=1 if server rejects profiles
- Simplify LITELLM_ENABLE_PYROSCOPE in config_settings; document Pyroscope env vars as required with no default
- Add pyroscope_profiling to sidebar (Alerting & Monitoring)
- pyproject.toml: pyroscope-io as required dep on non-Windows (marker), in proxy extra

* proxy: add PYROSCOPE_SAMPLE_RATE env, use verbose logging, fix int type

- Add optional PYROSCOPE_SAMPLE_RATE env (integer, no default)
- Pass sample_rate to pyroscope.configure() as int for pyroscope-io
- Replace print with verbose_proxy_logger (info/warning)
- Document PYROSCOPE_SAMPLE_RATE in config_settings.md

* Address Greptile PR feedback: Pyroscope optional, docs, tests, docstring

- pyproject.toml: mark pyroscope-io as optional=true (proxy extra only)
- Add docs/my-website/docs/proxy/pyroscope_profiling.md (fix broken sidebar link)
- Add tests/test_litellm/proxy/test_pyroscope.py for _init_pyroscope()
- proxy_server: fix _init_pyroscope docstring (required server/app name, sample rate as int)

* Update litellm/proxy/proxy_server.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix(model_info): Add missing tpm/rpm for Gemini models (#21175)

Several Gemini models (TTS, native-audio, robotics, gemma) were missing
tpm/rpm values, causing test_get_model_info_gemini to fail.

Added conservative default values (tpm=250000, rpm=10) for preview models.
gemini-2.5-flash-preview-tts gets tpm=4000000, rpm=10.

Co-authored-by: OpenClaw <openclaw@users.noreply.github.com>

* fix(ci): Fix ruff lint error - unused import in vertex_ai_ingestion (#21178)

Co-authored-by: shin-bot-litellm <shin-bot-litellm@users.noreply.github.com>

* fix(ci): Fix mypy type errors across 6 files (#21179)

- vertex_ai/gemini: fix TypedDict assignment via explicit dict cast
- mcp_server: convert MutableMapping scope to dict for type safety
- pass_through_endpoints: simplify custom_body logic to fix type narrowing
- vector_store_endpoints: add Any annotation for dynamic hook return
- responses transformation: use dict() for Reasoning and setattr for dynamic field
- zscaler_ai_guard: add assert for api_base None check

Co-authored-by: shin-bot-litellm <shin-bot-litellm@users.noreply.github.com>

* fix(ci): Fix E2E login button selector - use exact match (#21176)

* fix(ci): Fix ruff lint error - unused import

Remove unused 'cast' import in vertex_ai_ingestion.py (ruff F401)

* fix(ci): Fix E2E login button selector - use exact match

Login button selector now matches both 'Login' and 'Login with SSO',
causing strict mode violation. Use { exact: true } to match only 'Login'.

---------

Co-authored-by: OpenClaw <openclaw@users.noreply.github.com>

* fix(mypy): Fix type errors across multiple files (#21180)

- vertex_ai/gemini/transformation.py: Fix TypedDict assignment via dict alias
- mcp_server/server.py: Convert ASGI scope to dict for type compatibility
- pass_through_endpoints.py: Add explicit Optional[dict] type annotation
- vector_store_endpoints/endpoints.py: Add Any type for dynamic proxy hook
- responses transformation.py: Use dict(Reasoning()) and setattr for compatibility
- zscaler_ai_guard.py: Add assert for api_base nullability

Co-authored-by: OpenClaw <openclaw@users.noreply.github.com>

* [Guardrails] Add guardrail pipeline support for conditional sequential execution (#21177)

* Add pipeline type definitions for guardrail pipelines

PipelineStep, GuardrailPipeline, PipelineStepResult, PipelineExecutionResult
with validation for actions (allow/block/next/modify_response) and modes.

* Export pipeline types from policy_engine types package

* Add optional pipeline field to Policy model

* Add pipeline executor for sequential guardrail execution

* Parse pipeline config in policy registry

* Add pipeline validation in policy validator

* Add pipeline resolution and managed guardrail tracking

* Resolve pipelines and exclude managed guardrails in pre-call

* Integrate pipeline execution into proxy pre_call_hook

* Add test guardrails for pipeline E2E testing

* Add example pipeline config YAML

* Add unit tests for pipeline type definitions

* Add unit tests for pipeline executor

* Update litellm/proxy/policy_engine/pipeline_executor.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Update litellm/proxy/utils.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Add pipeline flow builder UI for guardrail policies (#21188)

* Add pipeline type definitions for guardrail pipelines

PipelineStep, GuardrailPipeline, PipelineStepResult, PipelineExecutionResult
with validation for actions (allow/block/next/modify_response) and modes.

* Export pipeline types from policy_engine types package

* Add optional pipeline field to Policy model

* Add pipeline executor for sequential guardrail execution

* Parse pipeline config in policy registry

* Add pipeline validation in policy validator

* Add pipeline resolution and managed guardrail tracking

* Resolve pipelines and exclude managed guardrails in pre-call

* Integrate pipeline execution into proxy pre_call_hook

* Add test guardrails for pipeline E2E testing

* Add example pipeline config YAML

* Add unit tests for pipeline type definitions

* Add unit tests for pipeline executor

* Add pipeline column to LiteLLM_PolicyTable schema

* Add pipeline field to policy CRUD request/response types

* Add pipeline support to policy DB CRUD operations

* Add PipelineStep and GuardrailPipeline TypeScript types

* Add Zapier-style pipeline flow builder UI component

* Integrate pipeline flow builder with mode toggle in policy form

* Add pipeline display section to policy info view

* Add unit tests for pipeline in policy CRUD types

* Refactor policy form to show mode picker first with icon cards

* Add full-screen FlowBuilderPage component for pipeline editing

* Wire up full-screen flow builder in PoliciesPanel with edit routing

* Restyle flow builder to match dev-tool UI aesthetic

* Restyle flow builder cards to match reference design

* Update step card to expanded layout with stacked ON PASS / ON FAIL sections

* Add end card to flow builder showing return to normal control flow

* Add PipelineTestRequest type for test-pipeline endpoint

* Export PipelineTestRequest from policy_engine types

* Add POST /policies/test-pipeline endpoint

* Add testPipelineCall networking function

* Add PipelineStepResult and PipelineTestResult types

* Add test pipeline panel to flow builder with run button and results display

* Fix pipeline executor: inject guardrail name into metadata so should_run_guardrail allows execution

* Update litellm/proxy/policy_engine/pipeline_executor.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Update litellm/proxy/utils.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Update litellm/proxy/policy_engine/policy_endpoints.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Update litellm/proxy/policy_engine/pipeline_executor.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix(responses-bridge): extract list-format system content into instructions

When system message content is a list of content blocks
(e.g. [{"type": "text", "text": "..."}]) instead of a plain string,
the responses API bridge was passing it through as a role: system
message in the input items. APIs like ChatGPT Codex reject this
with "System messages are not allowed".

This happens when requests come through the Anthropic /v1/messages
adapter, which converts system prompts into list-format content blocks
in the OpenAI chat completions format.

Fix: extract text from list content blocks and concatenate into the
instructions parameter, matching the existing behavior for string
system content.

* test: add tests for system message extraction in responses bridge

Add three tests for convert_chat_completion_messages_to_responses_api:
- String system content → instructions
- List-format content blocks → instructions (the bug this PR fixes)
- Multiple system messages (mixed string and list) concatenated

* fix: add warning log for unexpected system content types

Address review feedback: add an else clause that logs a warning
for any system content that is neither str nor list, rather than
silently dropping it.

---------

Co-authored-by: yuneng-jiang <yuneng.jiang@gmail.com>
Co-authored-by: The Mavik <179817126+themavik@users.noreply.github.com>
Co-authored-by: themavik <themavik@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Ishaan Jaff <ishaanjaffer0324@gmail.com>
Co-authored-by: Alexsander Hamir <alexsanderhamirgomesbaptista@gmail.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: shin-bot-litellm <shin-bot-litellm@berri.ai>
Co-authored-by: OpenClaw <openclaw@users.noreply.github.com>
Co-authored-by: shin-bot-litellm <shin-bot-litellm@users.noreply.github.com>
sameetn pushed a commit to sameetn/litellm that referenced this pull request Feb 16, 2026
* Pyroscope: require PYROSCOPE_APP_NAME and PYROSCOPE_SERVER_ADDRESS, add UTF-8 locale hint

- No defaults for PYROSCOPE_APP_NAME or PYROSCOPE_SERVER_ADDRESS; fail at startup if unset when Pyroscope is enabled
- Set LANG/LC_ALL to C.UTF-8 when unset to reduce malformed_profile (invalid UTF-8) rejections
- Startup message suggests PYTHONUTF8=1 if server rejects profiles
- Simplify LITELLM_ENABLE_PYROSCOPE in config_settings; document Pyroscope env vars as required with no default
- Add pyroscope_profiling to sidebar (Alerting & Monitoring)
- pyproject.toml: pyroscope-io as required dep on non-Windows (marker), in proxy extra

* proxy: add PYROSCOPE_SAMPLE_RATE env, use verbose logging, fix int type

- Add optional PYROSCOPE_SAMPLE_RATE env (integer, no default)
- Pass sample_rate to pyroscope.configure() as int for pyroscope-io
- Replace print with verbose_proxy_logger (info/warning)
- Document PYROSCOPE_SAMPLE_RATE in config_settings.md

* Address Greptile PR feedback: Pyroscope optional, docs, tests, docstring

- pyproject.toml: mark pyroscope-io as optional=true (proxy extra only)
- Add docs/my-website/docs/proxy/pyroscope_profiling.md (fix broken sidebar link)
- Add tests/test_litellm/proxy/test_pyroscope.py for _init_pyroscope()
- proxy_server: fix _init_pyroscope docstring (required server/app name, sample rate as int)

* Update litellm/proxy/proxy_server.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant