Skip to content

feat(gateway): document support for Gemini AI Studio - #2354

Merged
steebchen merged 19 commits into
theopenco:mainfrom
RATCHAW:RATCHAW/support-document-attachments
May 28, 2026
Merged

steebchen merged 19 commits into
theopenco:mainfrom
RATCHAW:RATCHAW/support-document-attachments

Conversation

@RATCHAW

@RATCHAW RATCHAW commented May 20, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Adds OpenAI-style `type: "file"` content blocks to the chat completions API, routed to Gemini on Google AI Studio as `inline_data` parts.
  • New `document` capability flag on `ProviderModelMapping` gates routing/validation; 22 google-ai-studio Gemini variants marked document-capable.
  • The transform passes the user-supplied MIME through verbatim (Google is authoritative on per-model support); `parseGoogleUpstreamDocumentError` re-emits Google's `Unsupported MIME type: X` response as a typed `UnsupportedDocumentFormatError` so both non-streaming and streaming clients see a clean 400 with `mimeType` + `providerTarget` instead of a wrapped upstream blob.

Test plan

  • `pnpm vitest run apps/gateway/src/chat/tools packages/actions` — 501 tests pass, includes new specs covering the transform, detection helper, the upstream-error parser (canonical / Vertex target / trailing-period / non-doc errors / RTF 500 / garbage), and the Gemini `document: true` flag presence.
  • `pnpm --filter @llmgateway/models --filter @llmgateway/actions --filter gateway --filter api build` — clean across touched packages.
  • `pnpm format` applied; lint-staged hooks ran cleanly on commit.
  • Live smoke: POST `/v1/chat/completions` to local gateway with `gemini-2.5-flash` and a small base64 PDF `type: "file"` block; verify 200; then repeat with `application/msword` and verify a 400 with `{ message: "Document MIME type \"application/msword\" is not supported by Google AI Studio." }`.

Summary by CodeRabbit

  • New Features

    • Document/file attachments in chats: upload, send, persist, include in shared snapshots/forks, and downloadable links in the UI.
  • Improvements

    • Models/providers expose a document capability so routing and validation respect file inputs.
    • Gateway returns clearer 400 errors for invalid/unsupported document formats (streaming and non‑streaming).
    • Client emits document telemetry and handles persistence/retry flows.
  • Tests

    • Added coverage for file-message handling and upstream document error mapping.
  • Documentation

    • New "Document Reading" docs and changelog entry with examples and error guidance.

Review Change Stack

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 20, 2026 •

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 060c28ec-3f69-454a-b49a-5a39c29288cb

📥 Commits

Reviewing files that changed from the base of the PR and between ddd37d6 and e32dab4.

⛔ Files ignored due to path filters (1)
  • apps/ui/public/changelog/document-reading.png is excluded by !**/*.png
📒 Files selected for processing (1)
  • apps/ui/src/content/changelog/2026-05-26-document-reading-support.md

Walkthrough

Adds OpenAI-style file message content, provider document capability flags, DB persistence for message.documents, gateway routing/validation for document-capable providers, Google transform + upstream error parsing, playground UI/submit/persistence, docs, and tests.

Changes

Document Input Support

Layer / File(s) Summary
Types and DB schema
packages/models/src/types.ts, packages/models/src/models.ts, apps/playground/src/lib/fetch-models.ts, packages/db/src/schema.ts
Adds FileContent + isFileContent, adds ProviderModelMapping.document and ApiModelProviderMapping.document, and adds message.documents DB column.
Google models document flags
packages/models/src/models/google.ts
Marks many Google Gemini provider entries with document: true capability.
API request/response schemas & persistence
apps/gateway/src/chat/schemas/completions.ts, apps/api/src/routes/chats.ts, apps/api/src/routes/internal-models.ts, apps/api/src/routes/public-chat-shares.ts
Adds file content to completions schema; adds documents JSON-string field to message schemas and shared snapshots; includes document in internal /internal/models mappings; persists/selects documents in share/fork/add/get flows.
Document detection & validation
apps/gateway/src/chat/tools/messages-contain-documents.ts, apps/gateway/src/chat/tools/validate-model-capabilities.ts, apps/gateway/src/chat/tools/messages-contain-documents.spec.ts
New messagesContainDocuments util; validateModelCapabilities accepts hasDocuments and enforces provider document support; tests added.
Google transform & upstream error parsing
packages/actions/src/transform-google-messages.ts, packages/actions/src/transform-google-messages.spec.ts
Transforms file blocks to Google inline_data (parse base64 data URLs); add InvalidFileContentError, UnsupportedDocumentFormatError, and parseGoogleUpstreamDocumentError with tests.
Gateway routing & upstream handling
apps/gateway/src/chat/chat.ts
Compute hasDocuments, thread through validate/filtering/auto-routing/provider selection/fallbacks, parse Google upstream document MIME rejections in streaming and non-streaming flows, and log typed pre-upstream input errors.
Global error handler
apps/gateway/src/app.ts
Handle InvalidFileContentError and UnsupportedDocumentFormatError with 400 JSON responses and warnings.
Playground integration & UI
apps/playground/src/components/playground/chat-page-client.tsx, apps/playground/src/components/playground/chat-ui.tsx, apps/playground/src/lib/fetch-models.ts
Expose supportsDocuments, hydrate stored documents into UI file parts, extend ChatUI to accept documents in onUserMessage, render documentParts, include documents in AI request parts and persistence.
Shared snapshot UI parsing
apps/playground/src/app/share/[shareId]/page.tsx
Add StoredDocumentPart shape and isStoredDocumentPart guard; parse message.documents JSON into UI file parts.
Docs & changelog
apps/docs/content/features/documents.mdx, apps/ui/src/content/changelog/2026-05-26-document-reading-support.md
New feature docs describing file content block usage, encoding, supported MIME types, error cases, and changelog entry.
Tests/specs
packages/actions/src/transform-google-messages.spec.ts, apps/gateway/src/chat/tools/messages-contain-documents.spec.ts
Extend tests for Google file block transform, upstream error parsing, and messagesContainDocuments + provider capability assertions.

Estimated code review effort:
🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs:

  • theopenco/llmgateway#2227: Related shared-chat snapshot and fork flow changes that this PR extends to include documents.
  • theopenco/llmgateway#2230: Related capability-validation and routing gating changes; both PRs modify per-model/provider capability checks.

Suggested reviewers:

  • smakosh
  • steebchen
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(gateway): document support for Gemini AI Studio' accurately describes the primary change: adding document attachment support to the gateway for Google's Gemini models via the file content block.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@RATCHAW
RATCHAW marked this pull request as draft May 20, 2026 17:12

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 60df122907

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/actions/src/transform-google-messages.ts
@RATCHAW
RATCHAW marked this pull request as ready for review May 20, 2026 20:19

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
apps/api/src/routes/chats.ts (2)

922-933: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Shared chat snapshots currently drop documents.

Line 903 selects documents, but Line 922-933 does not serialize it into chat_share.messages. Shared views/forks will silently lose document attachments.

💡 Suggested fix in snapshot mapping
 			messages: messages.map((message) => ({
 				id: message.id,
 				role: message.role,
 				content: message.content,
 				images: message.images,
 				audios: message.audios,
+				documents: message.documents,
 				reasoning: message.reasoning,
 				tools: message.tools,
 				metadata: message.metadata,
 				sequence: message.sequence,
 				createdAt: message.createdAt.toISOString(),
 			})),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/api/src/routes/chats.ts` around lines 922 - 933, The messages mapping
that builds chat_share.messages drops the documents field, so update the
messages.map block (the code that produces chat_share.messages) to include the
documents property from each message (e.g., documents: message.documents) and
ensure each document is serialized into a JSON-safe form (e.g., map document
objects to plain fields or call toJSON/serialize) so shared snapshots preserve
attachments; locate the messages.map call in this module and add documents
serialization alongside id, role, content, images, audios, reasoning, tools,
metadata, sequence, and createdAt.

1675-1686: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Include documents in add-message response payload.

Line 1659 persists documents, but the response object (Line 1675-1686) omits it, creating a contract mismatch with read endpoints.

💡 Suggested response fix
 			message: {
 				id: newMessage.id,
 				role: newMessage.role as "user" | "assistant" | "system",
 				content: newMessage.content,
 				images: newMessage.images,
 				audios: (newMessage as any).audios ?? null,
+				documents: (newMessage as any).documents ?? null,
 				reasoning: newMessage.reasoning,
 				tools: newMessage.tools ?? null,
 				metadata: newMessage.metadata ?? null,
 				sequence: newMessage.sequence,
 				createdAt: newMessage.createdAt.toISOString(),
 			},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/api/src/routes/chats.ts` around lines 1675 - 1686, The add-message
response omits the persisted documents field, causing a mismatch with read
endpoints; update the response object constructed for the new message (the block
that builds message: { id: newMessage.id, role: ..., createdAt: ... }) to
include documents (e.g., documents: newMessage.documents ?? null) so the payload
mirrors what was persisted and matches the read endpoints' contract.
apps/playground/src/components/playground/chat-page-client.tsx (1)

1066-1152: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve documents in the edit/retry flow.

This wires documents into create/load, but buildEditedUserMessage() and handleEditUserMessage() still only keep images/audio. Editing a user message with documents will resend without the files, so the regenerated response no longer matches what the UI shows.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/playground/src/components/playground/chat-page-client.tsx` around lines
1066 - 1152, The edit/retry flow drops documents because buildEditedUserMessage
and handleEditUserMessage only preserve images/audios; update both to also
preserve and pass documents (e.g., include documents?: string[] or serialized
JSON in the same spots images/audio are handled), ensure the edited message body
includes ...(documents?.length ? { documents: JSON.stringify(documents) } : {})
when constructing the payload and when calling addMessage.mutateAsync or retry
send so edited/resend operations include the original document attachments.
apps/playground/src/components/playground/chat-ui.tsx (1)

1023-1078: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reject unsupported attachments instead of silently dropping them.

When supportsDocuments is true the picker accepts any file, but this submit path only forwards MIME families that are enabled for the selected model. If a user picks an image/audio file for a model that lacks that capability, the attachment is discarded with no feedback. Please validate files before clearing/submitting and surface an error for unsupported types.

Also applies to: 1328-1345

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/playground/src/components/playground/chat-ui.tsx` around lines 1023 -
1078, Before building parts, validate the selected files against the model
capabilities (supportsImages, supportsAudio, supportsDocuments) and reject
unsupported attachments instead of dropping them: iterate the files array and
for each file check its mediaType (using mediaType?.startsWith("image/"),
mediaType?.startsWith("audio/"), and
isDocumentMediaType()/getDocumentMediaType()) and if any file’s type isn’t
allowed given the current supports* flags, surface a user-visible error (e.g.,
set form error or toast) and abort submission/clearing so parts isn’t built with
silently dropped files; ensure this validation runs in the same submit flow that
constructs parts and also in the other similar block referenced (around the
1328-1345 area).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/api/src/routes/chats.ts`:
- Line 648: Remove the unnecessary `as any` casts on the message properties and
access them directly (use message.audios and message.documents like you already
do for message.images, message.reasoning, and message.tools); update the code in
the chats route where `documents: (message as any).documents ?? null` and the
`audios` line appear to simply read `documents: message.documents ?? null` and
`audios: message.audios ?? null`; if TypeScript flags a type mismatch, fix the
local `message` variable's type (or the handler's input type) to the correct
message schema/interface so the compiler recognizes `audios` and `documents` as
defined.

In `@apps/gateway/src/app.ts`:
- Around line 142-149: The 400 response created by the c.json call in app.ts
currently omits structured metadata; update the returned JSON to include
mimeType and providerTarget from the thrown error (e.g., error.mimeType and
error.providerTarget or fields on the document-format error object) so clients
can consume unsupported-document errors reliably. Locate the c.json call that
returns { error: true, status: 400, message: error.message } and add mimeType
and providerTarget properties (falling back to null/undefined if absent) to that
response object; ensure you still return HTTP 400.

In `@apps/gateway/src/chat/chat.ts`:
- Around line 427-429: The specific-provider rate-limit fallback filters in this
file currently omit the documents capability check and can reroute hasDocuments
requests to providers lacking file support; update those fallback predicate(s)
(the code paths invoked when a provider is 429’ed) to include the same documents
guard used by filterEligibleModelProviders(): if (options.hasDocuments &&
provider.document !== true) return false (or equivalent boolean check), and
apply this change to all similar fallback blocks in the file (the other
specific-provider rate-limit fallback predicates referenced alongside
filterEligibleModelProviders()) so document requests are never forwarded to
providers without document support.

In `@apps/gateway/src/chat/schemas/completions.ts`:
- Around line 56-69: The current z.object for the "file" content block allows an
empty file object because file_data and file_id are optional; update the inner
z.object (the one assigned to the "file" key inside the z.literal("file")
branch) to add a .refine(...) that enforces at least one of file_data or file_id
is present, providing a clear error message (e.g., "either file_data or file_id
must be provided"); keep file_data and file_id as optional strings but use the
refine predicate to check Boolean(file_data) || Boolean(file_id) and attach the
message to the schema so validation fails early.

In `@apps/gateway/src/chat/tools/messages-contain-documents.spec.ts`:
- Around line 59-63: The test currently silently skips missing models in the
loop over expectedDocumentModelIds by using "if (!model) { continue; }", which
can hide a missing Gemini model; change this to explicitly fail the test when a
model is not found by replacing the continue with an assertion or throw (e.g.,
use expect(model).toBeDefined() or throw new Error(`Missing model ${id}`)) so
that the test fails if any expectedDocumentModelIds entry has no matching item
in models; update references in the spec to expectedDocumentModelIds, models,
and model accordingly.

In `@packages/actions/src/transform-google-messages.ts`:
- Around line 157-170: The parseFileDataUrl function currently lowercases the
captured MIME with match[1].toLowerCase(), which mutates user-supplied MIME;
change parseFileDataUrl to return the MIME verbatim (use match[1] unchanged) so
file_data MIME is preserved exactly as provided, and update any downstream
tests/allowlist expectations (e.g., the mixed-case MIME test) to match the
preserved-case behavior.

---

Outside diff comments:
In `@apps/api/src/routes/chats.ts`:
- Around line 922-933: The messages mapping that builds chat_share.messages
drops the documents field, so update the messages.map block (the code that
produces chat_share.messages) to include the documents property from each
message (e.g., documents: message.documents) and ensure each document is
serialized into a JSON-safe form (e.g., map document objects to plain fields or
call toJSON/serialize) so shared snapshots preserve attachments; locate the
messages.map call in this module and add documents serialization alongside id,
role, content, images, audios, reasoning, tools, metadata, sequence, and
createdAt.
- Around line 1675-1686: The add-message response omits the persisted documents
field, causing a mismatch with read endpoints; update the response object
constructed for the new message (the block that builds message: { id:
newMessage.id, role: ..., createdAt: ... }) to include documents (e.g.,
documents: newMessage.documents ?? null) so the payload mirrors what was
persisted and matches the read endpoints' contract.

In `@apps/playground/src/components/playground/chat-page-client.tsx`:
- Around line 1066-1152: The edit/retry flow drops documents because
buildEditedUserMessage and handleEditUserMessage only preserve images/audios;
update both to also preserve and pass documents (e.g., include documents?:
string[] or serialized JSON in the same spots images/audio are handled), ensure
the edited message body includes ...(documents?.length ? { documents:
JSON.stringify(documents) } : {}) when constructing the payload and when calling
addMessage.mutateAsync or retry send so edited/resend operations include the
original document attachments.

In `@apps/playground/src/components/playground/chat-ui.tsx`:
- Around line 1023-1078: Before building parts, validate the selected files
against the model capabilities (supportsImages, supportsAudio,
supportsDocuments) and reject unsupported attachments instead of dropping them:
iterate the files array and for each file check its mediaType (using
mediaType?.startsWith("image/"), mediaType?.startsWith("audio/"), and
isDocumentMediaType()/getDocumentMediaType()) and if any file’s type isn’t
allowed given the current supports* flags, surface a user-visible error (e.g.,
set form error or toast) and abort submission/clearing so parts isn’t built with
silently dropped files; ensure this validation runs in the same submit flow that
constructs parts and also in the other similar block referenced (around the
1328-1345 area).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6d1f6a2e-e3ba-42f2-b4f4-1aa7001799db

📥 Commits

Reviewing files that changed from the base of the PR and between 2df52d4 and 8ca1691.

⛔ Files ignored due to path filters (4)
  • apps/code/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
  • apps/playground/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
  • apps/ui/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
  • ee/admin/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
📒 Files selected for processing (17)
  • apps/api/src/routes/chats.ts
  • apps/api/src/routes/internal-models.ts
  • apps/gateway/src/app.ts
  • apps/gateway/src/chat/chat.ts
  • apps/gateway/src/chat/schemas/completions.ts
  • apps/gateway/src/chat/tools/messages-contain-documents.spec.ts
  • apps/gateway/src/chat/tools/messages-contain-documents.ts
  • apps/gateway/src/chat/tools/validate-model-capabilities.ts
  • apps/playground/src/components/playground/chat-page-client.tsx
  • apps/playground/src/components/playground/chat-ui.tsx
  • apps/playground/src/lib/fetch-models.ts
  • packages/actions/src/transform-google-messages.spec.ts
  • packages/actions/src/transform-google-messages.ts
  • packages/db/src/schema.ts
  • packages/models/src/models.ts
  • packages/models/src/models/google.ts
  • packages/models/src/types.ts

Comment thread apps/api/src/routes/chats.ts Outdated
Comment thread apps/gateway/src/app.ts
Comment thread apps/gateway/src/chat/chat.ts
Comment thread apps/gateway/src/chat/schemas/completions.ts
Comment thread apps/gateway/src/chat/tools/messages-contain-documents.spec.ts Outdated
Comment thread packages/actions/src/transform-google-messages.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8ca1691302

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/api/src/routes/chats.ts
function parseFileDataUrl(
fileData: string,
): { mimeType: string; data: string } | null {
const match = fileData.match(/^data:([^;,]+);base64,(.*)$/i);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Parse file_data URLs with MIME parameters

The file_data parser only accepts data:<mime>;base64,... and rejects valid data URLs like data:text/plain;charset=utf-8;base64,... because of the strict regex. This causes legitimate document payloads to be treated as invalid before reaching Google, breaking text document uploads that include MIME parameters.

Useful? React with 👍 / 👎.

RATCHAW and others added 3 commits May 21, 2026 13:01
- Drop unnecessary `as any` casts on message.audios / message.documents
- Return mimeType and providerTarget on UnsupportedDocumentFormatError 400
- Add hasDocuments guard to specific-provider rate-limit fallback filter
- Require file_data or file_id on `file` content blocks via schema refine
- Fail document-capability spec when expected model is missing
- Preserve MIME case verbatim in parseFileDataUrl
- Throw typed InvalidFileContentError so invalid file blocks return 400
- Preserve documents in shared/forked chat snapshots

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Parse and emit `documents` as file parts in the public shared chat
snapshot so uploaded files appear alongside text/images on /share/[id].
Regenerate API clients to expose the new field.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/api/src/routes/chats.ts (1)

1679-1690: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Return documents in the addMessage response payload.

documents is accepted and persisted, but the created-message response omits it (around Line 1684). Clients using the POST response directly won’t receive document attachments until a refetch.

Suggested fix
 		message: {
 			id: newMessage.id,
 			role: newMessage.role as "user" | "assistant" | "system",
 			content: newMessage.content,
 			images: newMessage.images,
 			audios: newMessage.audios ?? null,
+			documents: newMessage.documents ?? null,
 			reasoning: newMessage.reasoning,
 			tools: newMessage.tools ?? null,
 			metadata: newMessage.metadata ?? null,
 			sequence: newMessage.sequence,
 			createdAt: newMessage.createdAt.toISOString(),
 		},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/api/src/routes/chats.ts` around lines 1679 - 1690, The addMessage
response payload in chats.ts builds the message object from newMessage but omits
the persisted documents field; update the response construction inside the
addMessage handler to include documents: newMessage.documents (or
newMessage.documents ?? null) alongside images/audios/tools/metadata so clients
receive document attachments immediately in the created message response.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@apps/api/src/routes/chats.ts`:
- Around line 1679-1690: The addMessage response payload in chats.ts builds the
message object from newMessage but omits the persisted documents field; update
the response construction inside the addMessage handler to include documents:
newMessage.documents (or newMessage.documents ?? null) alongside
images/audios/tools/metadata so clients receive document attachments immediately
in the created message response.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6d92fa04-ad6d-4723-8d34-7b933f8416e3

📥 Commits

Reviewing files that changed from the base of the PR and between 8ca1691 and 2a57d87.

⛔ Files ignored due to path filters (4)
  • apps/code/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
  • apps/playground/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
  • apps/ui/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
  • ee/admin/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
📒 Files selected for processing (10)
  • apps/api/src/routes/chats.ts
  • apps/api/src/routes/public-chat-shares.ts
  • apps/gateway/src/app.ts
  • apps/gateway/src/chat/chat.ts
  • apps/gateway/src/chat/schemas/completions.ts
  • apps/gateway/src/chat/tools/messages-contain-documents.spec.ts
  • apps/playground/src/app/share/[shareId]/page.tsx
  • packages/actions/src/transform-google-messages.spec.ts
  • packages/actions/src/transform-google-messages.ts
  • packages/db/src/schema.ts

RATCHAW and others added 7 commits May 25, 2026 08:30
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@steebchen
steebchen enabled auto-merge May 27, 2026 08:29

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/models/src/models/google.ts (1)

42-42: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add document: true to google-vertex provider capability configs to match AI Studio

In packages/models/src/models/google.ts, all google-ai-studio provider entries that support documents set document: true, while the corresponding google-vertex entries for the same Gemini modelNames omit it (0/22 document-capable mappings for Vertex). Since packages/models/src/models.ts defines document as input to the model: "auto" router/capability validator, this omission can stop Vertex from being selected/allowed for file/inline document inputs even though Google Vertex Gemini supports document parts via REST inlineData (base64 + mimeType). [1]

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/models/src/models/google.ts` at line 42, In
packages/models/src/models/google.ts update the provider capability configs for
"google-vertex" entries to include document: true for each Gemini modelName that
already has document: true under "google-ai-studio" (i.e., mirror the
document-capable mappings); locate the provider entries named "google-vertex"
and add the document: true flag in their capability object so the auto
router/capability validator in packages/models/src/models.ts recognizes Vertex
as supporting file/inline document inputs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/models/src/models/google.ts`:
- Line 42: In packages/models/src/models/google.ts update the provider
capability configs for "google-vertex" entries to include document: true for
each Gemini modelName that already has document: true under "google-ai-studio"
(i.e., mirror the document-capable mappings); locate the provider entries named
"google-vertex" and add the document: true flag in their capability object so
the auto router/capability validator in packages/models/src/models.ts recognizes
Vertex as supporting file/inline document inputs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8044d7f6-7ce1-400d-8737-963a1d9225e1

📥 Commits

Reviewing files that changed from the base of the PR and between b763ba1 and ddd37d6.

⛔ Files ignored due to path filters (4)
  • apps/code/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
  • apps/playground/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
  • apps/ui/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
  • ee/admin/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
📒 Files selected for processing (2)
  • apps/gateway/src/chat/chat.ts
  • packages/models/src/models/google.ts

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
auto-merge was automatically disabled May 27, 2026 16:53

Head branch was pushed to by a user without write access

@steebchen
steebchen merged commit 6337ed1 into theopenco:main May 28, 2026
12 checks passed
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