Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions apps/web/config/chat-models.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,29 @@
version: 1

models:
# Default: Google Gemini. Reached at
# CHAT_BASE_URL=https://generativelanguage.googleapis.com/v1beta/openai,
# which is also where chat falls back when CHAT_BASE_URL is unset.
# Default: Google Gemini, reached through OpenRouter
# (CHAT_BASE_URL=https://openrouter.ai/api/v1).
#
# Model ids here are the BARE ids Google's endpoint expects. The `google/`
# prefix belongs only to the `preset:` field, which names a bundled behavior
# entry — see packages/core/src/llm/presets.ts.
# Ids are sent to the endpoint verbatim, so they carry OpenRouter's `google/`
# vendor prefix. Talking to Google's own compatibility endpoint
# (https://generativelanguage.googleapis.com/v1beta/openai, also the fallback
# when CHAT_BASE_URL is unset) instead? Drop the prefix from `id:` — it
# expects the bare ids. The `preset:` field is unaffected either way: it names
# a bundled behavior entry, not a model on the endpoint.
primary:
id: gemini-2.5-flash
id: google/gemini-2.5-flash

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep bare IDs for the built-in Gemini endpoint

When CHAT_BASE_URL is unset—the supported default path—resolveChatEndpoint still selects Google's compatibility endpoint (apps/web/src/server/chat-endpoint.ts:155-175), and the documented .env.example also points there. This configuration now sends google/gemini-2.5-* verbatim even though that endpoint expects bare Gemini IDs, so primary, fast, and reasoning chat requests fail for default and documented Google deployments. Keep the shipped IDs bare, or change the actual endpoint default and provide a separate configuration for direct Google users.

Useful? React with 👍 / 👎.

preset: google/gemini-2.5-flash

# The cheap tier. Its preset sets reasoning `default: none`, so routine work
# does not pay for thinking tokens.
fast:
id: gemini-2.5-flash-lite
id: google/gemini-2.5-flash-lite
preset: google/gemini-2.5-flash-lite

# The reasoning tier. 2.5 Pro always reasons, so its preset omits the `none`
# level rather than claiming a capability the endpoint would reject.
deep:
id: gemini-2.5-pro
id: google/gemini-2.5-pro
preset: google/gemini-2.5-pro

# Talking to something else instead? Any OpenAI-compatible endpoint works —
Expand Down
7 changes: 5 additions & 2 deletions services/document-converter/src/docling.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* docling-serve client — the consolidation of the old ocr-worker's
* docling_runner.py. Same conversion parameters (to_formats=["md"], do_ocr,
* docling_runner.py. Same conversion parameters (to_formats=md, do_ocr,
* do_table_structure, image_export_mode=placeholder); failures surface as
* typed ServiceErrors instead of opaque 500s.
*/
Expand All @@ -25,7 +25,10 @@ export const doclingConvertFile: DoclingConvert = async (config, file, filename)

const form = new FormData();
form.append("files", new Blob([new Uint8Array(file)]), filename);
form.append("to_formats", '["md"]');
// One repeated form field per format. docling-serve validates each entry
// against its OutputFormat enum, so a JSON-encoded array ("[\"md\"]")
// arrives as a single bogus member and the request fails 422.
form.append("to_formats", "md");
form.append("do_ocr", "true");
form.append("do_table_structure", "true");
form.append("image_export_mode", "placeholder");
Expand Down
2 changes: 1 addition & 1 deletion services/document-converter/test/docling.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe("doclingConvertFile outgoing request", () => {
expect(form).toBeInstanceOf(FormData);
expect(form!.get("md_page_break_placeholder")).toBe(PAGE_BREAK_PLACEHOLDER);
// Pre-existing conversion parameters stay intact.
expect(form!.get("to_formats")).toBe('["md"]');
expect(form!.get("to_formats")).toBe("md");
expect(form!.get("do_ocr")).toBe("true");
expect(form!.get("do_table_structure")).toBe("true");
expect(form!.get("image_export_mode")).toBe("placeholder");
Expand Down
Loading