feat: add Gemini embeddings support + Letta compatibility fixes

Cherry-picked from decolua/9router#148 (author: xuandung38 / Hồ Xuân Dũng <me@hxd.vn>)

- Add Google AI (Gemini) embeddings support for /v1/embeddings endpoint
- Add Gemini embedding models: gemini-embedding-001, text-embedding-005, text-embedding-004
- Inject missing object/created fields for Letta and strict OpenAI clients
- Strip Azure-specific fields (prompt_filter_results, content_filter_results) from responses
- Fix Dockerfile: copy open-sse directory into Docker runner stage

Skipped: whitelist message field stripping (commit 3/7/8) — too aggressive for all providers
Skipped: default stream=false change (commit 9) — behavior change needs further review
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Hồ Xuân Dũng
2026-02-20 15:01:10 +07:00
committed by decolua
parent e1e5a81613
commit a57a8ce206
5 changed files with 154 additions and 21 deletions

View File

@@ -760,6 +760,22 @@ export async function handleChatCore({ body, modelInfo, credentials, log, onCred
? translateNonStreamingResponse(responseBody, targetFormat, sourceFormat)
: responseBody;
// Ensure OpenAI-required fields are present (needed for Letta and other strict clients)
if (!translatedResponse.object) translatedResponse.object = "chat.completion";
if (!translatedResponse.created) translatedResponse.created = Math.floor(Date.now() / 1000);
// Strip Azure-specific non-standard fields
if (translatedResponse.prompt_filter_results !== undefined) {
delete translatedResponse.prompt_filter_results;
}
if (translatedResponse?.choices) {
for (const choice of translatedResponse.choices) {
if (choice.content_filter_results !== undefined) {
delete choice.content_filter_results;
}
}
}
// Add buffer and filter usage for client (to prevent CLI context errors)
if (translatedResponse?.usage) {
const buffered = addBufferToUsage(translatedResponse.usage);