discussion(runtime): define bounded recovery for provider-rejected native PDF inputs
- Dominant language
- TypeScript
- Stars
- 5.4k
- Forks
- 502
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 715
Description
## Problem
#3164 intentionally leaves ordinary provider failures on the existing bounded `ModelFailure` path. A later design may want to retry a request without PDF file parts when OpenAI or Anthropic rejects the document, but automatic retry is not yet a safe invariant.
Provider errors may be ambiguous, a request may already have consumed billable work, and an in-stream failure is materially different from a request-level rejection. Retrying based on free-text matching could duplicate cost, hide unrelated invalid requests, or create inconsistent durable/provider-attempt history.
## Desired outcome
Define whether Maka can recognize a provider-level PDF rejection with enough structured evidence to perform at most one safe fallback request without the rejected PDFs. Ambiguous cases must remain ordinary bounded model failures.
## Investigation scope
1. Capture exact structured error shapes, HTTP status, and request timing for native OpenAI Chat, OpenAI Responses, and Anthropic Messages PDF rejections.
2. Distinguish:
- a request-level rejection before any response stream or tool effect;
- an in-stream failure after provider work began;
- generic invalid-request failures with no PDF-specific authority.
3. Decide whether any provider exposes stable enough structured evidence for a one-shot PDF-free fallback. Do not rely on wording-only classification.
4. Specify accounting and durability:
- each physical provider call remains a distinct canonical attempt;
- a fallback cannot duplicate the user or steering message;
- the retry latch is bounded to one;
- PDF bytes and request bodies never enter errors, logs, RuntimeEvents, or diagnostics.
5. If no provider offers sufficient evidence, document that no automatic retry is supported and keep the existing `ModelFailure` behavior.
## Acceptance criteria for an implementation follow-up
- Only a named, structured, request-level PDF rejection can admit a PDF-free retry.
- Ambiguous or in-stream failures do not retry.
- The fallback request replaces each rejected file part with one bounded explanation while preserving the durable user-message identity.
- Usage/accounting records both physical attempts without claiming one logical success erased the rejected attempt.
- Retry behavior is consistent across current Turn, restart recovery, and steering.
- Regression tests prove the retry latch cannot loop.
## Non-goals
- General invalid-request retry.
- PDF parsing, encryption detection, page counting, or MIME validation; track those in #3284.
- Claiming PDF support for a new provider.
- Uploading the PDF to another service.
## References
- Parent delivery: #3164
- OpenAI file inputs: https://developers.openai.com/api/docs/guides/file-inputs
- Anthropic PDF requirements: https://platform.claude.com/docs/en/build-with-claude/pdf-support
Disclosure: this issue was drafted with OpenAI Codex assistance and reviewed and approved by the human contributor.
Contributor guide
Assessment
This issue has not been assessed yet.