Skip to content

Preserve billed usage when OpenAI response parsing fails - #3

Open
isaacbmiller wants to merge 2 commits into
integration/lm15-1.5.0-patchesfrom
fix/preserve-billed-usage
Open

isaacbmiller wants to merge 2 commits into
integration/lm15-1.5.0-patchesfrom
fix/preserve-billed-usage

Conversation

@isaacbmiller

@isaacbmiller isaacbmiller commented Oct 23, 2026 •

Copy link
Copy Markdown

Bug

A completed OpenAI Chat/Responses reply can contain valid billed usage and a malformed tool call (for example, no function name). lm15 raises the correct ProviderError, but discards the usage. DSPy's native-only migration then loses those billed tokens.

Fix

Preserve the original error and attach an accounting-only error.partial response with empty content and finish_reason="error". Use each dialect's existing usage reader on the already-decoded body; do not reparse malformed output or treat it as a successful response. Invalid telemetry cannot mask the original error. Sync and async callers share these readers.

This covers explicit OpenAI Chat/Responses parser errors and compatible providers sharing those parsers. HTTP-status failures, streaming and other dialects are unchanged. CONTRACT_PIN is unchanged.

This PR targets integration/lm15-1.5.0-patches, DSPy's current source pin, to keep the diff limited to this fix. It does not propose merging the existing downstream patch stack into fork main.

Validation

  • 61 new source regression cases pass, including zero/missing/invalid usage, original error metadata, successful output and both sync/async dialects.
  • Full source suite: 3,832 passed, 9 skipped, two reserved-IP connect-timeout failures. Both failures also reproduce at the unchanged source pin in this orb; exact-release upstream CI is green: https://github.com/lm15-dev/lm15-python/actions/runs/38822533894.
  • Strict conformance, exact pinned contract harness (all directions), and type gate pass; zero new package type findings.
  • DSPy's four billed-usage regressions fail before and pass after. Failure-lifecycle and engine-execution suites: 69 passed.
  • After the normal vendor import in [6/6] Make LiteLLM optional; retain compatibility fallback stanfordnlp/dspy#10719, the LiteLLM-free DSPy suite passes: 3,059 passed, 341 skipped, 2 xfailed. All five installed-wheel packaging checks pass, and the installed wheel retains the 22 billed tokens on the malformed reply. This replaces the earlier temporary import-redirect validation.
  • This PR's 34 GitHub CI checks pass, including all Linux/macOS/Windows Python 3.10–3.14 test legs, contract and type checks.

ampagent and others added 2 commits October 23, 2026 16:47
Keep the original ProviderError and attach an accounting-only partial Response using each dialect’s existing usage reader. Decode the body once; leave successful output parsing and HTTP diagnostics unchanged.

Signed-off-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03
Co-authored-by: Isaac Miller <isaac@cmpnd.ai>
Signed-off-by: Amp <amp@ampcode.com>
Co-authored-by: Isaac Miller <isaac@cmpnd.ai>
Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03

Copy link
Copy Markdown
Author

@greptileai review

isaacbmiller pushed a commit to stanfordnlp/dspy that referenced this pull request Oct 23, 2026
Use bundled lm15 for built-in LM execution without compatibility fallback. Move hosted embeddings to the OpenAI SDK, replace the proxy test fixture, and update installation, provider, cache, deployment and API documentation.

Import the source-owned billed-usage fix from cmpnd-ai/lm15-python#3 so malformed native replies retain their accounting without retries, cache or history writes.

Co-authored-by: Isaac Miller <isaac@cmpnd.ai>
Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03
isaacbmiller pushed a commit to stanfordnlp/dspy that referenced this pull request Oct 23, 2026
Use bundled lm15 for built-in LM execution without compatibility fallback. Move hosted embeddings to the OpenAI SDK, replace the proxy test fixture, and update installation, provider, cache, deployment and API documentation.

Import the source-owned billed-usage fix from cmpnd-ai/lm15-python#3 so malformed native replies retain their accounting without retries, cache or history writes.

Co-authored-by: Isaac Miller <isaac@cmpnd.ai>
Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03
isaacbmiller pushed a commit to stanfordnlp/dspy that referenced this pull request Oct 26, 2026
Use bundled lm15 for built-in LM execution without compatibility fallback. Move hosted embeddings to the OpenAI SDK, replace the proxy test fixture, and update installation, provider, cache, deployment and API documentation.

Import the source-owned billed-usage fix from cmpnd-ai/lm15-python#3 so malformed native replies retain their accounting without retries, cache or history writes.

Co-authored-by: Isaac Miller <isaac@cmpnd.ai>
Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03
isaacbmiller pushed a commit to stanfordnlp/dspy that referenced this pull request Oct 26, 2026
Use bundled lm15 for built-in LM execution without compatibility fallback. Move hosted embeddings to the OpenAI SDK, replace the proxy test fixture, and update installation, provider, cache, deployment and API documentation.

Import the source-owned billed-usage fix from cmpnd-ai/lm15-python#3 so malformed native replies retain their accounting without retries, cache or history writes.

Co-authored-by: Isaac Miller <isaac@cmpnd.ai>
Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03
isaacbmiller pushed a commit to stanfordnlp/dspy that referenced this pull request Oct 26, 2026
Use bundled lm15 for built-in LM execution without compatibility fallback. Move hosted embeddings to the OpenAI SDK, replace the proxy test fixture, and update installation, provider, cache, deployment and API documentation.

Import the source-owned billed-usage fix from cmpnd-ai/lm15-python#3 so malformed native replies retain their accounting without retries, cache or history writes.

Co-authored-by: Isaac Miller <isaac@cmpnd.ai>
Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03
isaacbmiller pushed a commit to stanfordnlp/dspy that referenced this pull request Oct 26, 2026
Use bundled lm15 for built-in LM execution without compatibility fallback. Move hosted embeddings to the OpenAI SDK, replace the proxy test fixture, and update installation, provider, cache, deployment and API documentation.

Import the source-owned billed-usage fix from cmpnd-ai/lm15-python#3 so malformed native replies retain their accounting without retries, cache or history writes.

Co-authored-by: Isaac Miller <isaac@cmpnd.ai>
Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03
isaacbmiller pushed a commit to stanfordnlp/dspy that referenced this pull request Oct 27, 2026
Use bundled lm15 for built-in LM execution without compatibility fallback. Move hosted embeddings to the OpenAI SDK, replace the proxy test fixture, and update installation, provider, cache, deployment and API documentation.

Import the source-owned billed-usage fix from cmpnd-ai/lm15-python#3 so malformed native replies retain their accounting without retries, cache or history writes.

Co-authored-by: Isaac Miller <isaac@cmpnd.ai>
Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03
isaacbmiller pushed a commit to stanfordnlp/dspy that referenced this pull request Oct 28, 2026
Use bundled lm15 for built-in LM execution without compatibility fallback. Move hosted embeddings to the OpenAI SDK, replace the proxy test fixture, and update installation, provider, cache, deployment and API documentation.

Import the source-owned billed-usage fix from cmpnd-ai/lm15-python#3 so malformed native replies retain their accounting without retries, cache or history writes.

Co-authored-by: Isaac Miller <isaac@cmpnd.ai>
Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03
isaacbmiller pushed a commit to stanfordnlp/dspy that referenced this pull request Oct 28, 2026
Use bundled lm15 for built-in LM execution without compatibility fallback. Move hosted embeddings to the OpenAI SDK, replace the proxy test fixture, and update installation, provider, cache, deployment and API documentation.

Import the source-owned billed-usage fix from cmpnd-ai/lm15-python#3 so malformed native replies retain their accounting without retries, cache or history writes.

Co-authored-by: Isaac Miller <isaac@cmpnd.ai>
Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03
isaacbmiller pushed a commit to stanfordnlp/dspy that referenced this pull request Oct 28, 2026
Use bundled lm15 for built-in LM execution without compatibility fallback. Move hosted embeddings to the OpenAI SDK, replace the proxy test fixture, and update installation, provider, cache, deployment and API documentation.

Import the source-owned billed-usage fix from cmpnd-ai/lm15-python#3 so malformed native replies retain their accounting without retries, cache or history writes.

Co-authored-by: Isaac Miller <isaac@cmpnd.ai>
Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03
isaacbmiller added a commit to stanfordnlp/dspy that referenced this pull request Oct 28, 2026
* Remove LiteLLM and document the native-only migration

Use bundled lm15 for built-in LM execution without compatibility fallback. Move hosted embeddings to the OpenAI SDK, replace the proxy test fixture, and update installation, provider, cache, deployment and API documentation.

Import the source-owned billed-usage fix from cmpnd-ai/lm15-python#3 so malformed native replies retain their accounting without retries, cache or history writes.

Co-authored-by: Isaac Miller <isaac@cmpnd.ai>
Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03

* Preserve OpenRouter cross-model fallback in native requests

Accept the provider-owned models/route policy only on OpenRouter and document the flat generation-option migration. Cover public sync/async Predict wire behavior and refusal on unrelated routes.

Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03
Co-authored-by: Isaac Miller <isaac@cmpnd.ai>

* Keep LiteLLM available as an optional installation extra

Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03
Co-authored-by: Isaac Miller <isaac@cmpnd.ai>

* Retain optional LiteLLM compatibility and restore docs Pipenv files

Keep native-first auto selection, strict lm15, and explicit litellm with the
optional extra. Preserve pre-I/O fallback, native endpoint improvements,
and lazy SDK imports. Exercise installed-wheel compatibility separately
from dependency-free core CI.

Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03
Co-authored-by: Isaac Miller <isaac@cmpnd.ai>

* Stop testing optional LiteLLM compatibility in CI

Amp-Thread-ID: https://ampcode.com/threads/T-01a135b1-7d59-73cc-a17c-57b7b3454c03
Co-authored-by: Isaac Miller <isaac@cmpnd.ai>

---------

Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: Isaac Miller <isaac@cmpnd.ai>
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.

2 participants