Repository navigation
feat(ocr): Vertex AI DeepSeek-OCR provider - #10395
Closed
diegosouzapw wants to merge 7 commits into
Closed
diegosouzapw wants to merge 7 commits into
diegosouzapw wants to merge 7 commits into
Conversation
Adds VERTEX_DEEPSEEK_TRANSFORMATION (request/response mapping for the Vertex AI DeepSeek OCR MaaS endpoint) and registers the "vertex-deepseek-ocr" provider in OCR_PROVIDERS, modeled on litellm's VertexAIDeepSeekOCRConfig. buildRequest treats the resolved baseUrl as the complete Vertex endpoint URL (project/location resolved upstream), matching the existing Mistral passthrough pattern.
Adds resolveVertexOcrAccessToken (mints a Vertex OAuth access token from a Service Account JSON apiKey, reusing open-sse/executors/vertex.ts's existing JWT-bearer exchange — no new OAuth flow) and resolveVertexOcrBaseUrl (derives the project/location "openapi/chat/ completions" endpoint from providerSpecificData or the Service Account JSON's project_id). Both live in open-sse/handlers/ocr.ts, not the src/app/api/v1/ocr route, since routes may not import executor implementations directly (EXECUTOR_IMPORT_RESTRICTION in eslint.config.mjs) — the route re-exports/consumes them across that boundary. handleOcr now prefers credentials.accessToken over apiKey so the minted token (not the raw Service Account JSON) is sent upstream.
Adds the vertex-deepseek-ocr row to the /v1/ocr provider table and a short section on its Vertex AI auth/endpoint resolution, and lists the new provider/model id in openapi.yaml alongside mistral and azure-document-intelligence.
Adds `i-have-adhd` as the 5th entry in OUTPUT_STYLE_CATALOG — a port of the github.com/ayghri/i-have-adhd skill (MIT), following the same integration shape as ponytail. Action-first output shaping: the next action leads, multi-step work is numbered, no preamble/recap/closers — which also trims output tokens. lite/full/ultra levels in en + pt-BR, each ending in SHARED_BOUNDARIES so code, paths, commands, errors and URLs stay verbatim. The agent-harness-specific upstream rules (restate plan state, time estimates) are reworded as conditionals so they hold for plain chat clients too. Per the D-A1 registry contract, one catalog entry is the whole change: the injector, the settings panel, the Zod schema and the telemetry all enumerate the catalog, so no other production file moves. Dedicated test mirrors ponytail-catalog.test.ts (7 tests).
…ovider-scoped error rules (#10335) agentrouter.org signals temporary quota exhaustion with HTTP 403/400 and a Chinese body (用户额度不足) instead of 429, so clients like Claude Code treat it as permanent and abort, and the fallback engine classified it as a generic apikey AUTH_ERROR. New registry open-sse/config/upstreamStatusRestatement.ts restates those statuses to 429 with a synthetic Retry-After at a single hook in chatCore's providerFailure block (after parseUpstreamError), so classification, combo aggregation and the client response all see a retryable error. 无权访问模型 (permanently no model access) is veto-listed and never restated. agentrouter classification rules are registered in providerErrorRules.ts and reach the real checkFallbackError path through resolveRuleMatchBody() with an exclusive FULL_TEXT_RULE_PROVIDERS allowlist — every other provider keeps its previous behavior byte-for-byte. Known limitations tracked in #10334: the rules' scope field is informational (persistence applies per-model lockout for agentrouter), the 403-only model-access rule has no production path yet, and errors embedded in 200 SSE streams are not restated. Refs #10334
Collaborator
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the backlog issue #10282 opened alongside PR-A: Vertex AI DeepSeek-OCR as the third
/v1/ocrprovider, using the transformation layer introduced in #10283 (pattern migrated from litellm'sllms/vertex_ai/ocr/deepseek_transformation.py).feat/ocr-multi-provider) — it needs theOcrTransformationinterface and the generic handler dispatch. After #10283 merges, retarget torelease/v3.8.50(gh pr edit --base release/v3.8.50, then verify with--json baseRefName).VERTEX_DEEPSEEK_TRANSFORMATION+ thevertex-deepseek-ocrregistry entry, mapping the upstream response onto the canonical MistralOCRResponseshape like the other providers.open-sse/handlers/ocr.ts, not in the route:src/app/**may not importopen-sse/executors/*directly (EXECUTOR_IMPORT_RESTRICTIONeslint boundary).Validation
tests/unit/ocr-*.test.ts— 46/46, including 16 new cases (6 transformation + 10 route/auth-resolution).typecheck:coreexit 0 · eslint/prettier clean on touched files.Not validated live: no GCP test project was available, so the real
deepseek-ai/deepseek-ocr-maasresponse was never exercised end-to-end. Per Hard Rule #18 this shipped through the TDD path (new integration, not a bug repro), but a live smoke test is worth doing before anyone relies on it in production.Closes #10282