Skip to content

refactor(clients/lm): extract _common_prep and _rewrite_for_text_comp…#24

Open
isaacbmiller wants to merge 2 commits intomainfrom
isaac/refactor-lm-streaming
Open

refactor(clients/lm): extract _common_prep and _rewrite_for_text_comp…#24
isaacbmiller wants to merge 2 commits intomainfrom
isaac/refactor-lm-streaming

Conversation

@isaacbmiller
Copy link
Copy Markdown

…Collapses boilerplate shared across the 6 litellm wrapper functions (chat/text/responses x sync/async). Also fixes alitellm_completion streaming to pass dspy-identifier-stamped headers into litellm.acompletion (previously passed None).

…letion

Collapses boilerplate shared across the 6 litellm wrapper functions
(chat/text/responses x sync/async). Also fixes alitellm_completion
streaming to pass dspy-identifier-stamped headers into litellm.acompletion
(previously passed None).

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 23, 2026

Greptile Summary

This PR collapses per-function boilerplate (dict copy, rollout_id pop, header stamping, cache defaulting) into _common_prep, and lifts the chat-to-text-completion transform into _rewrite_for_text_completion, making the six litellm wrappers a thin shell around those two helpers. It also fixes a real bug: alitellm_completion streaming previously called _get_stream_completion_fn with no headers argument (passing None into the inner litellm.acompletion) — the refactor routes the stamped headers correctly through _common_prep and into both the streaming and non-streaming paths.

Confidence Score: 5/5

Safe to merge — behavior is equivalent or strictly improved across all six wrappers.

All six wrappers preserve existing behaviour; the only functional delta is the confirmed bug-fix for missing headers in async streaming. No new logic paths, no schema changes, no security concerns. All remaining findings are P2 at most.

No files require special attention.

Important Files Changed

Filename Overview
dspy/clients/lm.py Extracts _common_prep and _rewrite_for_text_completion to de-duplicate boilerplate across 6 litellm wrappers; also fixes alitellm_completion streaming to forward stamped headers to both _get_stream_completion_fn and litellm.acompletion.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[incoming request dict] --> B["_common_prep(request, cache)"]
    B --> C["body = dict(request)\nbody.pop('rollout_id')"]
    C --> D["headers = _add_dspy_identifier_to_headers(...)"]
    D --> E["cache = cache or {no-cache defaults}"]
    E --> F["returns (body, headers, cache)"]

    F --> G{caller type}

    G -- chat --> H["_get_stream_completion_fn(body, cache, sync, headers)"]
    H -- stream set --> I["stream_completion()"]
    H -- stream None --> J["litellm.completion / acompletion\n(cache, num_retries, headers, **body)"]

    G -- text --> K["_rewrite_for_text_completion(body)"]
    K --> L["body: model, api_key, api_base, prompt mutated in-place"]
    L --> M["litellm.text_completion / atext_completion\n(cache, num_retries, headers, **body)"]

    G -- responses --> N["_convert_chat_request_to_responses_request(body)"]
    N --> O["litellm.responses / aresponses\n(cache, num_retries, headers, **body)"]
Loading

Reviews (2): Last reviewed commit: "refactor(clients/lm): make _rewrite_for_..." | Re-trigger Greptile

Comment thread dspy/clients/lm.py Outdated
Return None and drop the body = _rewrite_for_text_completion(body) pattern
at call sites. body is already a fresh copy produced by _common_prep, so the
previous dual mutation+return signature was misleading.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@isaacbmiller
Copy link
Copy Markdown
Author

@greptile

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